LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;

ENTITY PFIO IS
    PORT (
        -- RST signal
        RST : IN STD_LOGIC;
        -- CLOCK signal
        CLK : IN STD_LOGIC;
        -- INPUT RESULT for PF registers
        RES : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
        -- INPUT BITS for which register is written
        WC : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
        -- INPUT CONTROL BIT for written enable
        WE : IN STD_LOGIC;
        -- INPUT BITS for which register output result to C1
        F1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
        -- INPUT BITS for which register output result to C2
        F2 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
        -- OUTPUT RESULT for result C1 out
        C1 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
        -- OUTPUT RESULT for result C2 out
        C2 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
    );
END PFIO;

ARCHITECTURE PFIOArch OF PFIO IS

    COMPONENT PFREG IS
        PORT (
            -- RST signal
            RST : IN STD_LOGIC;
            -- indication bit ('1': Start read and close out ;'0': Start out and close read)  
            READ_EN : IN STD_LOGIC;
            -- CLOCK signal
            CLK : IN STD_LOGIC;
            -- read data
            D : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
            -- out data
            Q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
        );
    END COMPONENT;

    -- Player Finger Register control bits
    SIGNAL PFR_C : STD_LOGIC_VECTOR(3 DOWNTO 0);
    -- Player Finger Register output bits
    SIGNAL PFR_O : STD_LOGIC_VECTOR(31 DOWNTO 0);
    -- Write enable control bits
    SIGNAL WEC : STD_LOGIC_VECTOR(3 DOWNTO 0);
    -- MUX_out result
    SIGNAL MUX_out : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
    -- Generate PF Registers
    U_POL_REG : PFREG PORT MAP(RST => RST, READ_EN => PFR_C(0), CLK => CLK, D => RES, Q => PFR_O(7 DOWNTO 0));
    U_POR_REG : PFREG PORT MAP(RST => RST, READ_EN => PFR_C(1), CLK => CLK, D => RES, Q => PFR_O(15 DOWNTO 8));
    U_PTL_REG : PFREG PORT MAP(RST => RST, READ_EN => PFR_C(2), CLK => CLK, D => RES, Q => PFR_O(23 DOWNTO 16));
    U_PTR_REG : PFREG PORT MAP(RST => RST, READ_EN => PFR_C(3), CLK => CLK, D => RES, Q => PFR_O(31 DOWNTO 24));

    -- For write enable to obstruct MUX_out
    WEC <= "0000" WHEN (WE = '0') ELSE
        "1111";

    -- MUX_out implement
    WITH WC SELECT
        MUX_out <= "0001" WHEN "00",
        "0010" WHEN "01",
        "0100" WHEN "10",
        "1000" WHEN "11",
        "ZZZZ" WHEN OTHERS;

    -- Descided final PFR_C
    PFR_C <= MUX_out AND WEC;

    -- F1 MUX_out
    WITH F1 SELECT
        C1 <= PFR_O(7 DOWNTO 0) WHEN "00",
        PFR_O(15 DOWNTO 8) WHEN "01",
        PFR_O(23 DOWNTO 16) WHEN "10",
        PFR_O(31 DOWNTO 24) WHEN "11",
        "ZZZZZZZZ" WHEN OTHERS;

    --F2 MUX_out
    WITH F2 SELECT
        C2 <= PFR_O(7 DOWNTO 0) WHEN "00",
        PFR_O(15 DOWNTO 8) WHEN "01",
        PFR_O(23 DOWNTO 16) WHEN "10",
        PFR_O(31 DOWNTO 24) WHEN "11",
        "ZZZZZZZZ" WHEN OTHERS;

END PFIOArch; -- PFIOArch